// MapViewerPage.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import "../components" 1.0
Item {
    id: mapContainer
    width: innerStackView.width
    height: innerStackView.height
    property string robotId: ""
    property string currentMapName: "default"
    property var positionValueX: "0.0"
    property var positionValueY: "0.0"
    property var statusValue: "正常"
    property real minimumWidth: 400
    property real minimumHeight: 300
    property real initialWidth: 800
    property real initialHeight: 600
    property real mapMinX: 0
    property real mapMinY: 0
    property real mapMaxX: 0
    property real mapMaxY: 0
    property var cmd_get_map_site_information: 1301 //获取当前地图中站点信息
    property var stations: []  // 添加站点信息属性

    Connections {
        target: heartbeatModel
        function onRobotStatusUpdated(robotId, status, currentTarget, battery, x, y) {
            // 检查机器人ID
            if (robotId === mapContainer.robotId) {
                // 更新位置信息
                positionValueX = x.toFixed(2)
                positionValueY = y.toFixed(2)

                // 更新导航状态
                statusValue = status + (currentTarget ? "→" + currentTarget : "")
            }
        }
    }
    /*
    Connections {
        target: robotController
        function onPositionUpdated(x, y, angle) {
            positionValueX = x.toFixed(2)
            positionValueY = y.toFixed(2)
        }
    }
    */
    Connections {
        target: robotController
        function onMapStationInformationUpdated(stationData) {
            console.log("接收到站点数据: " + stationData);
            // 获取站点详细信息
            handleStationUpdate(stationData);
        }
    }
    
    // 添加获取站点详细信息的函数
    function getStationDetails() {
        // 发送命令获取站点详细信息
        robotController.getMapSiteInformation(cmd_get_map_site_information); // 使用特定的cmdId
    }
    
    // 处理站点信息更新
    function handleStationUpdate(stationData) {
        try {
            const data = JSON.parse(stationData);
            if (data.stations) {
                // 保存站点数据用于绘制
                stations = data.stations;
                canvas.requestPaint();
            }
        } catch (e) {
            console.error("解析站点信息失败: " + e);
        }
    }

    Canvas {
        id: canvas
        anchors.fill: parent
        renderTarget: Canvas.FramebufferObject
        property real currentScale: 1.0
        property real offsetX: width / 2
        property real offsetY: height / 2

        // 数据模型
        ListModel { id: pointModel }
        ListModel { id: robotModel }

        // 窗口大小变化时重定位地图
        onWidthChanged: resetMapView()
        onHeightChanged: resetMapView()

        function resetMapView() {
            if (pointModel.count > 0) calculateCenter();
            requestPaint();
        }

        // 计算地图中心点和合适的缩放比例
        function calculateCenter() {
            let minX = Infinity, maxX = -Infinity;
            let minY = Infinity, maxY = -Infinity;
            
            for (let i = 0; i < pointModel.count; i++) {
                const p = pointModel.get(i);
                const x = p.x * 10 + 100;
                const y = p.y * 10;
                
                minX = Math.min(minX, x);
                maxX = Math.max(maxX, x);
                minY = Math.min(minY, y);
                maxY = Math.max(maxY, y);
            }
            
            if (minX === Infinity) return;
            
            const centerX = (minX + maxX) / 2;
            const centerY = (minY + maxY) / 2;
            
            canvas.offsetX = (canvas.width / 2) - centerX * canvas.currentScale;
            canvas.offsetY = (canvas.height / 2) + centerY * canvas.currentScale;
            
            // 根据地图尺寸自动调整缩放比例，使地图完整显示在视图中
            const mapWidth = maxX - minX;
            const mapHeight = maxY - minY;
            const scaleX = canvas.width / mapWidth;
            const scaleY = canvas.height / mapHeight;
            const idealScale = Math.min(scaleX, scaleY) * 0.9; // 留出10%的边距
            
            if (idealScale && idealScale > 0) {
                canvas.currentScale = idealScale;
            }
        }

        // 绘制逻辑（只绘制地图，不绘制机器人）
        onPaint: {
            const ctx = getContext("2d");
            ctx.resetTransform();
            ctx.clearRect(0, 0, width, height);

            // 坐标系变换：平移+Y轴反转
            ctx.translate(offsetX, offsetY);
            ctx.scale(currentScale, -currentScale);

            // 视口边界计算
            const visibleLeft = (-offsetX) / currentScale;
            const visibleTop = (offsetY - height) / currentScale; 
            const visibleRight = (width - offsetX) / currentScale;
            const visibleBottom = offsetY / currentScale;

            // 绘制点集（灰色）
            ctx.fillStyle = "gray";
            const pointRadius = Math.max(0.5, 3 / canvas.currentScale);
            for (let i = 0; i < pointModel.count; i++) {
                const p = pointModel.get(i);
                const x = p.x * 10 + 100;
                const y = p.y * 10;

                // 跳过屏幕外点
                if (x < visibleLeft || x > visibleRight || y < visibleTop || y > visibleBottom) continue;

                ctx.beginPath();
                ctx.arc(x, y, pointRadius, 0, Math.PI * 2);
                ctx.fill();
            }

            // 绘制站点连接线
            if (stations.length > 1) {
                ctx.strokeStyle = "#0066cc";
                ctx.lineWidth = Math.max(1, 2 / canvas.currentScale);

                // 按照desc分组站点，并找出每个lobe的起始和结束点
                const lobeGroups = {};

                stations.forEach(station => {
                    // 只处理有desc且非空的站点作为lobe的标识
                    if (station.desc && station.desc !== "") {
                        if (!lobeGroups[station.desc]) {
                            lobeGroups[station.desc] = {
                                startEndPoints: [],
                                allPoints: []
                            };
                        }
                        lobeGroups[station.desc].startEndPoints.push(station);
                    }
                });

                // 收集所有属于某个lobe的站点
                Object.keys(lobeGroups).forEach(lobeName => {
                    // 找到该lobe的第一个和最后一个带desc标签的站点的ID数字
                    const taggedStations = lobeGroups[lobeName].startEndPoints;
                    if (taggedStations.length === 0) return;

                    // 按ID排序
                    taggedStations.sort((a, b) => {
                        const numA = parseInt(a.id.replace("LM", ""));
                        const numB = parseInt(b.id.replace("LM", ""));
                        return numA - numB;
                    });

                    const firstTaggedId = parseInt(taggedStations[0].id.replace("LM", ""));
                    const lastTaggedId = parseInt(taggedStations[taggedStations.length - 1].id.replace("LM", ""));

                    // 收集介于这两个ID之间的所有站点（包括端点）
                    const lobeStations = stations.filter(station => {
                        const stationIdNum = parseInt(station.id.replace("LM", ""));
                        return stationIdNum >= firstTaggedId && stationIdNum <= lastTaggedId;
                    });

                    // 按ID排序
                    lobeStations.sort((a, b) => {
                        const numA = parseInt(a.id.replace("LM", ""));
                        const numB = parseInt(b.id.replace("LM", ""));
                        return numA - numB;
                    });

                    // 连接相邻的站点
                    for (let i = 0; i < lobeStations.length - 1; i++) {
                        const station1 = lobeStations[i];
                        const station2 = lobeStations[i + 1];

                        const x1 = station1.x * 10 + 100;
                        const y1 = station1.y * 10;
                        const x2 = station2.x * 10 + 100;
                        const y2 = station2.y * 10;

                        // 检查是否在视口内
                        if ((x1 < visibleLeft && x2 < visibleLeft) || 
                            (x1 > visibleRight && x2 > visibleRight) ||
                            (y1 < visibleTop && y2 < visibleTop) || 
                            (y1 > visibleBottom && y2 > visibleBottom)) {
                            continue;
                        }

                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.lineTo(x2, y2);
                        ctx.stroke();
                    }
                });
            }

            // 绘制站点ID
            if (stations.length > 0) {
                for (let i = 0; i < stations.length; i++) {
                    const station = stations[i];
                    const x = station.x * 10 + 100;
                    const y = station.y * 10;

                    // 检查是否在视口内
                    if (x < visibleLeft || x > visibleRight || y < visibleTop || y > visibleBottom) continue;

                    // 计算合适的圆形和字体大小（调整为更小的尺寸）
                    const circleRadius = Math.max(8, 10 / canvas.currentScale);
                    const fontSize = Math.max(6, Math.min(circleRadius * 0.8, 8 / canvas.currentScale));

                    // 保存当前上下文状态
                    ctx.save();

                    // 设置阴影效果增强视觉层次
                    ctx.shadowColor = "rgba(0, 0, 0, 0.3)";
                    ctx.shadowBlur = 2;
                    ctx.shadowOffsetX = 1;
                    ctx.shadowOffsetY = 1;

                    // 绘制圆形背景
                    ctx.fillStyle = "rgba(255, 255, 255, 0.9)"; // 半透明白色背景
                    ctx.beginPath();
                    ctx.arc(x, y, circleRadius, 0, Math.PI * 2);
                    ctx.fill();

                    ctx.strokeStyle = "#ff0000";
                    ctx.lineWidth = Math.max(1, 1 / canvas.currentScale);
                    ctx.stroke();

                    // 恢复上下文状态，自动清除阴影效果
                    ctx.restore();

                    // 绘制站点ID（需要反转Y轴缩放以保持文字正向显示）
                    ctx.save();
                    ctx.scale(1, -1);
                    ctx.fillStyle = "#333333"; // 深灰色文字
                    ctx.font = "bold " + fontSize + "px sans-serif";
                    ctx.textAlign = "center";
                    ctx.textBaseline = "middle";
                    ctx.fillText(station.id, x, -y);
                    ctx.restore();
                }
            }
        }

        // 鼠标交互
        MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            property real lastX: 0
            property real lastY: 0

            onPressed: (mouse) => {
                lastX = mouse.x;
                lastY = mouse.y;
            }

            onPositionChanged: (mouse) => {
                if (pressedButtons & Qt.LeftButton) {
                    canvas.offsetX += mouse.x - lastX;
                    canvas.offsetY += mouse.y - lastY;
                    lastX = mouse.x;
                    lastY = mouse.y;
                    canvas.requestPaint();
                    robotIndicator.requestPaint(); // 同时更新机器人位置
                }
            }

            onWheel: (wheel) => {
                const zoomFactor = 1.1;
                const scaleDelta = (wheel.angleDelta.y > 0) ? zoomFactor : 1/zoomFactor;
                canvas.currentScale *= scaleDelta;
                
                canvas.offsetX = (canvas.offsetX - wheel.x) * scaleDelta + wheel.x;
                canvas.offsetY = (canvas.offsetY - wheel.y) * scaleDelta + wheel.y;
                canvas.requestPaint();
                robotIndicator.requestPaint(); // 同时更新机器人位置
            }
        }
    }

    // 独立的机器人指示器
    RobotIndicator {
        id: robotIndicator
        anchors.fill: parent
        robotX: parseFloat(positionValueX)
        robotY: parseFloat(positionValueY)
        robotId: mapContainer.robotId
        statusValue: mapContainer.statusValue
        mapScale: canvas.currentScale
        mapOffsetX: canvas.offsetX
        mapOffsetY: canvas.offsetY
    }

    // 信号管理
    function disconnectSignals() {
        if (mapData) {
            mapData.pointsUpdated.disconnect(handlePointsUpdate);
            mapData.robotsUpdated.disconnect(handleRobotsUpdate);
            mapData.mapBoundsUpdated.disconnect(handleMapBoundsUpdate);
        }
    }

    function handlePointsUpdate(points) {
        if (!points || !canvas) return;
        
        canvas.offsetX = canvas.width / 2;
        canvas.offsetY = canvas.height / 2;
        
        pointModel.clear();
        const lodFactor = Math.max(1, Math.floor(1 / canvas.currentScale)); 
        const sampleStep = Math.max(1, Math.floor(points.length / (5000 * lodFactor)));
        
        for (let i = 0; i < points.length; i += sampleStep) {
            pointModel.append({ "x": points[i].x, "y": points[i].y });
        }
        
        canvas.calculateCenter();
        canvas.requestPaint();
    }

    function handleRobotsUpdate() {
        if (!mapData || !robotModel) return;
        
        robotModel.clear();
        mapData.getRobots().forEach(r => robotModel.append(r));
        canvas.requestPaint();
    }

    // 处理地图边界信息更新
    function handleMapBoundsUpdate(minX, minY, maxX, maxY) {
        mapContainer.mapMinX = minX;
        mapContainer.mapMinY = minY;
        mapContainer.mapMaxX = maxX;
        mapContainer.mapMaxY = maxY;
        console.log("接收到地图边界信息: minX=" + minX + ", minY=" + minY + ", maxX=" + maxX + ", maxY=" + maxY);
    }

    Component.onCompleted: {
        if (mapData) {
            mapData.pointsUpdated.connect(handlePointsUpdate);
            mapData.robotsUpdated.connect(handleRobotsUpdate);
            mapData.mapBoundsUpdated.connect(handleMapBoundsUpdate);
            // 检查robotId是否有效
            let mapPath;
            if (robotId && robotId.length > 0) {
                mapPath = "data/" + robotId + "/map/" + currentMapName + ".smap";
            } else {
                console.warn("Invalid robotId, loading default map");
                mapPath = "data/" + robotId + "/map/default.smap";
            }
            mapData.loadMap(mapPath);
        }
        // 获取站点信息
        getStationDetails();
        canvas.requestPaint();
    }

    Component.onDestruction: {
        disconnectSignals();
    }
}